/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#ifndef __DX_INPUTHANDLER_H__
#define __DX_INPUTHANDLER_H__

#pragma once

#include "IInputHandler.h"
#include <dinput.h>
#include "geom/Vector.h"
#include "Window.h"

namespace directx {

/**
 * \ingroup CoreEngine
 * 
 * The InputHandler class.
 * DirectInput implementation of the IInputHandler interface.
 *
 * \version 1.0
 *
 * \date 03-28-2007
 *
 * \author juckel
 *
 */
class InputHandler 
  : public IInputHandler
{
public:
	InputHandler(void);
	~InputHandler(void);

	/// Initializes the input devices. 
	/// InputDevices are initialized through IH_KEYBOARD | IH_MOUSE | IH_JOYSTICK
	bool init(HINSTANCE hInst, HWND hWnd, int inputDevices);
	
	/// Update the input devices and stores the data
	void update();

	/// Check if a certain button is pressed. Keycodes start with DIK_*
	bool isKeyPressed(int keycode) const;

	/// Returns the current mouse position
	math::Vector3 getRelMousePos()const;
	
	/// Inidicates, if a mouse button is pressed.
	/// 0 = LEFT_BUTTON, 1 = RIGHT_BUTTON, 2 = MIDDLE_BUTTON
	bool isMouseButtonPressed(int button) const;

	BYTE* getButtons();

	/// Returns the whole mouse state object
	DIMOUSESTATE2 getMouseState() const { return mouseBuffer; }




	/// Returns the current relative joystick position
	/// deprecated!
	math::Vector3 getRelJoystickPos() const;

	/// Returns the current relative joystick position of axis1
	math::Vector2f getJoystickAxis1Pos() const;

	/// Returns the current relative joystick position of axis2
	math::Vector2f getJoystickAxis2Pos() const;

	/// Inidicates, if a joystick button is pressed.
	bool isJoystickButtonPressed( int button) const;

	/// Returns the joystick buttons as a byte array
	BYTE* getJoystickButtons();

	/// Returns the whole joystick state object
	DIJOYSTATE getJoystickState() const { return joystickBuffer; }




	virtual void restore();
	virtual void release();

	// The callback function to enumerate the installed joystick devices
	static BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );

	// The callback function for checking and adjusting the device's capabilities
	static BOOL CALLBACK EnumCapabilitiesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );

private:
	bool initKeyboard(HWND hWnd);
	bool initMouse(HWND hWnd);
	bool initJoystick(HWND hWnd);

	LPDIRECTINPUT8			lpDI; 
	LPDIRECTINPUTDEVICE8	lpDIKeyboardDevice; 
	LPDIRECTINPUTDEVICE8	lpDIMouseDevice; 
	LPDIRECTINPUTDEVICE8	lpDIJoystickDevice; 

	char keyboardBuffer[256];		// Keyboard state structure
	DIMOUSESTATE2 mouseBuffer;      // Mouse state structure
	DIJOYSTATE joystickBuffer;		// The Joystick state structure

	Window  *pMainWindow;
	bool     bRunning;
	HWND *pHwnd;
};

} // namespace

#endif
